﻿using System;
using gbL.NetBoard.Broadcast;

namespace gbL.NetBoard.Helpers
{
    public abstract class TypedMessageListener<T> where T : class
    {
        public TypedMessageListener(Blackboard messages)
        {
            Attach(messages);
        }

        public TypedMessageListener() : base() { }

        public void Attach(Blackboard messages)
        {
            if (Messages != null) 
                DetachAndRemoveFilters(Messages);
            AttachAndFilter(messages);
        }

        void OnMessageAddedHandler(object sender, ChangedEventArgs e)
        {
            T message = e.Entry.Message as T;
            OnMessageAdded(message);
        }

        void OnMessageRemovedHandler(object sender, ChangedEventArgs e)
        {
            T message = e.Entry.Message as T;
            OnMessageRemoved(message);
        }

        protected virtual Blackboard Messages { get; set; }

        protected virtual void DetachAndRemoveFilters(Blackboard blackboard)
        {
            blackboard.Broadcaster.Added -= new EventHandler<ChangedEventArgs>(OnMessageAddedHandler);
            blackboard.Broadcaster.Removed -= new EventHandler<ChangedEventArgs>(OnMessageRemovedHandler);
            blackboard.Broadcaster.RemoveFilterAddedByType(this, typeof(T));
            blackboard.Broadcaster.RemoveFilterRemovedByType(this, typeof(T));
        }

        protected virtual void AttachAndFilter(Blackboard blackboard)
        {
            blackboard.Broadcaster.Added += new EventHandler<ChangedEventArgs>(OnMessageAddedHandler);
            blackboard.Broadcaster.Removed += new EventHandler<ChangedEventArgs>(OnMessageRemovedHandler);
            blackboard.Broadcaster.FilterAddedByType(this, typeof(T));
            blackboard.Broadcaster.FilterRemovedByType(this, typeof(T));
            Messages = blackboard;
        }

        protected abstract void OnMessageAdded(T message);

        protected abstract void OnMessageRemoved(T message);
    }
}
